home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / E-Z Progress Bar 1.0a / ProgressClass.cp < prev    next >
Text File  |  1995-03-15  |  12KB  |  622 lines

  1. #include "ProgressClass.h"
  2.  
  3. ProgressClass::ProgressClass(short options)
  4. {
  5.     cancelButton=nil;
  6.     appleMenu=menu1=menu2=menu3=menu4=menu5=menu6=0;
  7.     minValue=maxValue=curValue=0.0;
  8.     
  9.     SetRect(&windowRect,wLeft, wTop, wRight, wBottom);
  10.  
  11.     theWindow=(WindowPtr) NewPtr(sizeof (WindowRecord));
  12.     theWindow=NewCWindow(theWindow, &windowRect, "\p", 0, noGrowDocProc, (WindowPtr) -1L, 0, 0L);
  13.  
  14.     kBarHeight=11;
  15.     kBarWidth=170;
  16.  
  17.     Point    colorPoint;
  18.     colorPoint.h=140;
  19.     colorPoint.v=90;
  20.     
  21. //    emptyColor=&qd.rgbHiliteColor;            //    This should work, but doesn't.  If you know how
  22.                                             //    to get the hilite color, email me!
  23.  
  24.     emptyColor.red=emptyColor.blue=emptyColor.green=0xFFFF;
  25.     progressColor.red=0x2C1B;
  26.     progressColor.green=0x2A25;
  27.     progressColor.blue=0xE159;
  28.     windowColor.red=windowColor.green=windowColor.blue=0xEEEE;
  29.     
  30.     progChisel.LiteDarkFrom(progressColor);
  31.     
  32.     progChisel.SetChiselWay(!chiselIn);
  33.     
  34.     useRGB=RGBAvailable();
  35.  
  36.     SetOptions(options);
  37.     PositionElements("\p");
  38. }
  39.  
  40. ProgressClass::~ProgressClass()
  41. {
  42.     HiliteMenus();
  43.     if (cancelButton)
  44.         DisposeControl(cancelButton);
  45.     if (theWindow) {
  46.         CloseWindow(theWindow);
  47.         DisposPtr((Ptr) theWindow);
  48.     }
  49. }
  50.  
  51. void    ProgressClass::SetOptions(short options)
  52. {
  53.     cancel=options & canCancel;
  54.     chiselF=options & chiselFrame;
  55.     chiselP=options & chiselBar;
  56.     grayWin=options & grayBack;
  57.     chiselH=options & fineChisel;
  58.     
  59.     if (!cancel && cancelButton)
  60.         HideControl(cancelButton);
  61.     else if (cancel && !cancelButton)
  62.         SetCancelButton();
  63. }
  64.  
  65. void    ProgressClass::SetMinMax(short min, short max)
  66. {
  67.     maxValue=max;
  68.     minValue=min;
  69.     curValue=minValue;
  70. }
  71.  
  72. void    ProgressClass::SetControlID(short controlID)
  73. {
  74.     if (controlID)
  75.         cancel=1;
  76.     else
  77.         cancel=0;
  78.     SetCancelButton(controlID);
  79. }
  80.  
  81. void    ProgressClass::SetTexts(Str255 windowTitle, Str255 paramText)
  82. {
  83.     GrafPtr    oldPort;
  84.     
  85.     GetPort(&oldPort);
  86.     SetPort(theWindow);
  87.     SetWTitle(theWindow, windowTitle);
  88.     
  89.     PositionElements(paramText);
  90.     InvalRgn(theWindow->visRgn);
  91.     SetPort(oldPort);
  92. }
  93.  
  94. void    ProgressClass::SetAppleMenu(short appleID)
  95. {
  96.     MenuHandle    theMenu=GetMHandle(appleID);
  97.     
  98.     if (theMenu) {
  99.         short items=CountMItems(theMenu);
  100.         Str255    theItem;
  101.         Boolean found=0;
  102.         
  103.         for(short i=1; i<=items && !found; i++) {
  104.             GetItem(theMenu, i, theItem);
  105.             if (theItem[1]=='-')
  106.                 found=1;
  107.         }
  108.         
  109.         appleDivider=(found) ? i-1 : 0;
  110.     }
  111.     appleMenu=appleID;
  112. }
  113.  
  114. void    ProgressClass::SetMenus(short m1, short m2, short m3, short m4, short m5, short m6, short m7, short m8)
  115. {
  116.     menu1=m1;
  117.     menu2=m2;
  118.     menu3=m3;
  119.     menu4=m4;
  120.     menu5=m5;
  121.     menu6=m6;
  122.     menu7=m7;
  123.     menu8=m8;
  124. }
  125.  
  126. void    ProgressClass::SetCancelButton(short controlID)
  127. {
  128.     if (cancelButton) {
  129.         DisposeControl(cancelButton);
  130.         cancelButton=nil;
  131.     }
  132.     if (cancel) {
  133.         short right=theWindow->portRect.right-20;
  134.         short bottom=theWindow->portRect.bottom-15;
  135.         
  136.         SetRect(&controlRect, right-70, bottom-20, right, bottom);
  137.     
  138.         if (controlID) {
  139.             cancelButton=GetNewControl(controlID, theWindow);
  140.             if (!cancelButton)
  141.                 cancelButton=NewControl(theWindow, &controlRect, "\pCancel", 1, 0, 0, 1, pushButProc, 0L);
  142.             MoveControl(cancelButton, controlRect.left, controlRect.top);
  143.         }
  144.         
  145.         else
  146.             cancelButton=NewControl(theWindow, &controlRect, "\pCancel", 1, 0, 0, 1, pushButProc, 0L);
  147.     
  148.         ShowControl(cancelButton);
  149.     }
  150. }
  151.     
  152.  
  153. void    ProgressClass::SetBar(short current)
  154. {
  155.     curValue=current;
  156.     DrawProgressBar();
  157. }
  158.  
  159. void    ProgressClass::SetBar(short current, Str255 paramText)
  160. {
  161.     ReplaceText(paramText);
  162.     SetBar(current);
  163. }
  164.  
  165. void    ProgressClass::SetBar(float current)
  166. {
  167.     current=(current<0.0) ? 0.0 : current;
  168.     current=(current>1.0) ? 1.0 : current;
  169.     if ((maxValue-minValue)>0.00001) {        //    Use this to account for float errors when "==" is used
  170.         maxValue=100;
  171.         minValue=0;
  172.     }
  173.     curValue=minValue+current*maxValue;
  174.     DrawProgressBar();
  175. }
  176.  
  177. void    ProgressClass::SetBar(float current, Str255 paramText)
  178. {
  179.     ReplaceText(paramText);
  180.     SetBar(current);
  181. }
  182.  
  183. void    ProgressClass::SetBarWidth(short width)
  184. {
  185.     GrafPtr    oldPort;
  186.     
  187.     GetPort(&oldPort);
  188.     SetPort(theWindow);
  189.     
  190.     kBarWidth=width;
  191.     PositionElements(progressText);
  192.     InvalRgn(theWindow->visRgn);
  193.     SetPort(oldPort);
  194. }
  195.  
  196. void    ProgressClass::SetBarHeight(short height)
  197. {
  198.     GrafPtr    oldPort;
  199.     
  200.     GetPort(&oldPort);
  201.     SetPort(theWindow);
  202.     
  203.     kBarHeight=height;
  204.     PositionElements(progressText);
  205.     InvalRgn(theWindow->visRgn);
  206.     SetPort(oldPort);
  207. }
  208.  
  209. void    ProgressClass::SetWindowColor(RGBColor theColor)
  210. {
  211.     GrafPtr    oldPort;
  212.     
  213.     GetPort(&oldPort);
  214.     SetPort(theWindow);
  215.     
  216.     RGBBackColor(&theColor);
  217.     InvalRgn(theWindow->visRgn);
  218.     
  219.     SetPort(oldPort);
  220. }
  221.  
  222. void    ProgressClass::PositionElements(Str255 paramText)
  223. {
  224.     //    Rectangle Positioning
  225.  
  226.     FontInfo    theFont;
  227.     GrafPtr        oldPort;
  228.     
  229.     GetPort(&oldPort);
  230.     SetPort(theWindow);
  231.     GetFontInfo(&theFont);
  232.         
  233.     short    left=(theWindow->portRect.right-theWindow->portRect.left)/2-kBarWidth/2;
  234.     short    top=(theWindow->portRect.bottom-theWindow->portRect.top)/2-kBarHeight/2-3;
  235.     
  236.     if (chiselH)
  237.         top+=4;    //    Fudge factor
  238.     
  239.     top+=2;        //    Fudge factor again
  240.     
  241.     SetRect(&emptyBar, left, top, left+kBarWidth, top+kBarHeight);
  242.     
  243.     frameBar=emptyBar;
  244.     InsetRect(&frameBar, -1, -1);
  245.     
  246.     if (chiselP)                                        
  247.         progressBar=progChisel.PreChisel(emptyBar);
  248.     else
  249.         progressBar=emptyBar;
  250.         
  251.     pBarWidth=progressBar.right-progressBar.left;                
  252.  
  253.     if (chiselF)
  254.         frameChisel.SetDefaultRect(frameBar);
  255.     if (chiselH) {
  256.         Rect    hairRect=frameBar;
  257.         InsetRect(&hairRect, -8, -8);
  258.         hairChisel.SetDefaultRect(hairRect);
  259.     }
  260.     
  261.     //    Text Positioning
  262.  
  263.     short    paramLength=StringWidth(paramText);
  264.     Rect        tempRect;
  265.         
  266.     if (chiselF)
  267.         tempRect=frameChisel.ChiselRect(frameBar);
  268.     else
  269.         tempRect=frameBar;
  270.         
  271.     top=tempRect.top-(theFont.ascent-theFont.leading*2);
  272.  
  273.     if (chiselH)
  274.         top-=2;
  275.         
  276.     textPoint.h=tempRect.left;
  277.     textPoint.v=top;
  278.     
  279.     maxCharWid=theFont.widMax;
  280.     
  281.     for (short i=0; i<=paramText[0]; i++)
  282.         progressText[i]=paramText[i];
  283.         
  284.     SetPort(oldPort);
  285. }
  286.  
  287. void    ProgressClass::ShowBarWindow()
  288. {
  289.     GrafPtr    oldPort;
  290.     
  291.     GetPort(&oldPort);
  292.     SetPort(theWindow);
  293.     
  294.     if (grayWin && useRGB)
  295.         RGBBackColor(&windowColor);
  296.     else
  297.         BackColor(whiteColor);
  298.     InvalRect(&theWindow->portRect);
  299.     ShowWindow(theWindow);
  300.     UpdateWindow();
  301.     
  302.     SetPort(oldPort);
  303. }
  304.  
  305. void    ProgressClass::HideBarWindow()
  306. {
  307.     HideWindow(theWindow);
  308.     HiliteMenus();
  309. }
  310.  
  311. void    ProgressClass::UpdateWindow()
  312. {
  313.     GrafPtr    oldPort;
  314.     
  315.     GetPort(&oldPort);
  316.     SetPort(theWindow);
  317.     
  318.     BeginUpdate(theWindow);
  319.     
  320.     EraseRect(&theWindow->portRect);
  321.     
  322.     DrawProgressText();
  323.     
  324.     FrameRect(&frameBar);
  325.     
  326.     if (chiselF)
  327.         frameChisel.Chisel();
  328.     if (chiselH)
  329.         hairChisel.HairChisel();
  330.         
  331.     DrawProgressBar();
  332.     if (cancel)
  333.         UpdateControls(theWindow, theWindow->visRgn);
  334.         
  335.     EndUpdate(theWindow);
  336.     SetPort(oldPort);
  337. }
  338.  
  339. void    ProgressClass::DrawProgressBar()
  340. {
  341.     RGBColor    backColor, foreColor;
  342.     PenState    oldState;
  343.     GrafPtr        oldPort;
  344.     
  345.     GetPort(&oldPort);
  346.     SetPort(theWindow);
  347.     GetPenState(&oldState);
  348.     
  349.     PenSize(1,1);
  350.     PenMode(patCopy);
  351.     
  352.     if (curValue>maxValue)
  353.         curValue=maxValue;
  354.     else if (curValue<minValue)
  355.         curValue=minValue;
  356.     
  357.     progressBar.right=progressBar.left+pBarWidth*(curValue-minValue)/maxValue;
  358.  
  359.     if (progressBar.right>progressBar.left)
  360.         emptyBar.left=progressBar.right;
  361.  
  362.     if (useRGB) {
  363.         GetBackColor(&backColor);
  364.         GetForeColor(&foreColor);
  365.         
  366.         RGBBackColor(&emptyColor);
  367.         EraseRect(&emptyBar);
  368.         
  369.         RGBBackColor(&progressColor);
  370.         EraseRect(&progressBar);
  371.         if (chiselP && (progressBar.right>progressBar.left))
  372.             progChisel.Chisel(progressBar);
  373.     }
  374.     
  375.     ForeColor(blackColor);
  376.     
  377.     emptyBar.left=progressBar.left;
  378.     
  379.     if (useRGB) {
  380.         RGBBackColor(&backColor);
  381.         RGBForeColor(&foreColor);
  382.     }
  383.     
  384.     SetPenState(&oldState);
  385.     SetPort(oldPort);
  386. }
  387.  
  388. void    ProgressClass::DrawProgressText()
  389. {
  390.     TextFont(0);
  391.     MoveTo(textPoint.h, textPoint.v);
  392.     DrawString(progressText);
  393. }
  394.  
  395. void    ProgressClass::ReplaceText(Str255 paramText)
  396. {
  397.     FontInfo    theFont;
  398.     GrafPtr        oldPort;
  399.     short        i, numEraseChars, curWidth;
  400.     Rect    tempRect;
  401.     
  402.     GetPort(&oldPort);
  403.     SetPort(theWindow);
  404.     GetFontInfo(&theFont);
  405.  
  406.     for (i=1; (i<=progressText[0]) && (paramText[i]==progressText[i]); i++)
  407.         ;
  408.         
  409.     numEraseChars=progressText[0]-i+1;
  410.     curWidth=StringWidth(progressText);
  411.     
  412.     SetRect(&tempRect, textPoint.h+(curWidth-numEraseChars*maxCharWid), textPoint.v-(theFont.descent+theFont.ascent), textPoint.h+curWidth, textPoint.v+theFont.descent);
  413.     EraseRect(&tempRect);
  414.     for (i=0; i<=paramText[0]; i++)
  415.         progressText[i]=paramText[i];
  416.  
  417.     DrawProgressText();
  418.     
  419.     SetPort(oldPort);
  420. }    
  421.  
  422.  
  423.  
  424. Boolean        ProgressClass::ReceivedEvent(Boolean *userCancel, Boolean *deactivate, WindowPtr *updateWindow)
  425. {
  426.     if (WaitNextEvent(everyEvent, &theEvent, 10, nil)) {
  427.     
  428.         switch (theEvent.what) {
  429.         
  430.             case keyDown:
  431.                 if (((theEvent.message & charCodeMask) == '.') && (theEvent.modifiers & cmdKey) && cancel) {
  432.                     HiliteControl(cancelButton, inButton);
  433.                     Delay(8, nil);
  434.                     HiliteControl(cancelButton, 0);
  435.                     *userCancel=1;
  436.                     *deactivate=0;
  437.                     *updateWindow=nil;
  438.                     return 1;
  439.                 }
  440.                 else
  441.                     return 0;
  442.             break;
  443.             
  444.             case mouseDown:
  445.                 WindowPtr    thisWindow;
  446.                 short    part=FindWindow(theEvent.where, &thisWindow);
  447.                 GrafPtr    oldPort;
  448.                 
  449.                 Point    where=theEvent.where;
  450.  
  451.                 GetPort(&oldPort);
  452.                 SetPort(theWindow);
  453.                 GlobalToLocal(&where);
  454.                 SetPort(oldPort);
  455.                 
  456.                 switch (part) {
  457.                     case inContent:
  458.                         if (thisWindow==theWindow) {
  459.                             if (FindControl(where, theWindow, nil))
  460.                                 if (TrackControl(cancelButton, where, nil)) {
  461.                                     *userCancel=1;
  462.                                     *deactivate=0;
  463.                                     *updateWindow=nil;
  464.                                     return 1;
  465.                                 }
  466.                         }
  467.                         else
  468.                             SysBeep(10);
  469.                         return 0;
  470.                     break;
  471.                     
  472.                     case inDrag:
  473.                         if (thisWindow==theWindow) {
  474.                             RgnHandle    grayRgn=GetGrayRgn();
  475.                             DragWindow(theWindow, theEvent.where, &(**grayRgn).rgnBBox);
  476.                         }
  477.                         return 0;
  478.                     break;
  479.                     
  480.                     case inMenuBar:
  481.                         long    menuSelection;
  482.                         
  483.                         DimMenus();
  484.                         menuSelection=MenuSelect(theEvent.where);
  485.                         HiliteMenu(0);
  486.                         
  487.                         short    menu=HiWord(menuSelection);
  488.                         short    item=LoWord(menuSelection);
  489.                         
  490.                         if (appleMenu==menu) {
  491.                             if (item<=appleDivider)
  492.                                 SysBeep(10);
  493.                             else {
  494.                                 Str255 itemString;
  495.                                 GetItem(GetMHandle(appleMenu), item, itemString);
  496.                                 OpenDeskAcc(itemString);
  497.                             }
  498.                         }
  499.                         return 0;
  500.                     break;
  501.                     
  502.                     default:
  503.                         return 0;
  504.                     break;
  505.                 }
  506.             break;
  507.         
  508.             case updateEvt:
  509.                 if ((WindowPtr) theEvent.message == theWindow) {
  510.                     UpdateWindow();
  511.                     return 0;
  512.                 }
  513.                 else {
  514.                     *updateWindow=(WindowPtr) theEvent.message;
  515.                     *userCancel=0;
  516.                     *deactivate=0;
  517.                     return 1;
  518.                 }
  519.             break;
  520.             
  521.             case activateEvt:
  522.  
  523.                 if (theEvent.modifiers & activeFlag) {
  524.                     SetCursor(&arrow);
  525.                     HiliteControl(cancelButton, 0);
  526.                     return 0;
  527.                 }
  528.                 else {
  529.                     HiliteControl(cancelButton, 255);
  530.                     if ((WindowPtr) theEvent.message!=theWindow) {
  531.                         *deactivate=1;
  532.                         *userCancel=0;
  533.                         *updateWindow=(WindowPtr) theEvent.message;
  534.                         return 1;
  535.                     }
  536.                     return 0;
  537.                 }
  538.             break;
  539.             
  540.             case diskEvt:
  541.                 if (HiWord(theEvent.message)!=noErr) {
  542.                     Point    thisPoint;
  543.                     
  544.                     DILoad();
  545.                     SetPt(&thisPoint, 120, 120);
  546.                     
  547.                     DIBadMount(thisPoint, theEvent.message);
  548.                     DIUnload();
  549.                     
  550.                     return 0;
  551.                 }
  552.                 
  553.             default:
  554.                 return 0;
  555.             break;
  556.         }
  557.     }
  558.     
  559.     return 0;
  560. }
  561.  
  562. void    ProgressClass::DeselectItems(short menuID)
  563. {
  564.     MenuHandle theMenu=GetMHandle(menuID);
  565.     
  566.     if (theMenu) {
  567.         DisableItem(theMenu, 0);
  568.         DrawMenuBar();
  569.     }
  570. }
  571.  
  572. void    ProgressClass::DimMenus()
  573. {
  574.     if (menu1)
  575.         DeselectItems(menu1);
  576.     if (menu2)
  577.         DeselectItems(menu2);
  578.     if (menu3)
  579.         DeselectItems(menu3);
  580.     if (menu4)
  581.         DeselectItems(menu4);
  582.     if (menu5)
  583.         DeselectItems(menu5);
  584.     if (menu6)
  585.         DeselectItems(menu6);
  586.     if (menu7)
  587.         DeselectItems(menu7);
  588.     if (menu8)
  589.         DeselectItems(menu8);
  590. }
  591.  
  592. void    ProgressClass::SelectItems(short menuID)
  593. {
  594.     MenuHandle theMenu=GetMHandle(menuID);
  595.     
  596.     if (theMenu) {
  597.         EnableItem(theMenu, 0);
  598.         DrawMenuBar();
  599.     }
  600. }
  601.  
  602. void    ProgressClass::HiliteMenus()
  603. {
  604.     if (menu1)
  605.         SelectItems(menu1);
  606.     if (menu2)
  607.         SelectItems(menu2);
  608.     if (menu3)
  609.         SelectItems(menu3);
  610.     if (menu4)
  611.         SelectItems(menu4);
  612.     if (menu5)
  613.         SelectItems(menu5);
  614.     if (menu6)
  615.         SelectItems(menu6);
  616.     if (menu7)
  617.         SelectItems(menu7);
  618.     if (menu8)
  619.         SelectItems(menu8);
  620. }
  621.  
  622.